import 'package:sow_app_core/src/entity/chapter.dart';
import 'package:sow_app_core/src/entity/novel.dart';
import 'package:sow_app_core/src/error/exception.dart';
import 'package:sow_app_core/src/usecase/novel_usecase.dart';
import 'package:test/test.dart';

import 'package:sow_app_mock/sow_app_mock.dart';

void main() {
  group('novel usecase test group', () {
    test(
      "should return list when call GetNovelListUseCase()",
      () async {
        // arrange
        final usecase = GetNovelListUseCase(MockNovelRepository());

        // act
        final list = await usecase(GetNovelListParams(null, null, null, null));

        // assert
        expect(list.length, greaterThan(0));
      },
    );
    test(
      "should return correct list when call GetNovelListUseCase() with valid title",
      () async {
        // arrange
        final usecase = GetNovelListUseCase(MockNovelRepository());

        // act
        final list =
            await usecase(GetNovelListParams("第6975颗繁星", null, null, null));

        // assert
        expect(list[0].title, "第6975颗繁星");
      },
    );
    test(
      "should return null when call GetNovelDetailUseCase() with invalid novelId",
      () async {
        // arrange
        final usecase = GetNovelDetailUseCase(MockNovelRepository());
        const novelId = "-1";
        Novel? novel;
        // act
        try {
          novel = await usecase(novelId);
          // assert
          expect(novel, throwsException);
        } on NovelNotfoundException catch (e) {
          expect(e, isA<NovelNotfoundException>());
        }
      },
    );
    test(
      "should return novel when call GetNovelDetailUseCase() with valid novelId",
      () async {
        // arrange
        final usecase = GetNovelDetailUseCase(MockNovelRepository());
        const novelId = "1";
        // act
        final result = await usecase(novelId);

        // assert
        expect(result, isNotNull);
        expect(result.title, "第6975颗繁星");
      },
    );
    test(
      "should return nothing when call IncreaseReadUseCase()",
      () async {
        // arrange
        final usecase = IncreaseReadUseCase(MockNovelRepository());
        const novelId = "1";
        // act
        await usecase(novelId);
        // assert
      },
    );
    test(
      "should return list of two objects when call GetNovelChapterList()",
      () async {
        // arrange
        final usecase = GetNovelChapterListUseCase(MockNovelRepository());
        const novelId = "1";
        // act
        final result = await usecase(novelId);

        // assert
        expect(result.length, 2);
      },
    );
    test(
      "should return chapter of two objects when call GetNovelChapterContent()",
      () async {
        // arrange
        final usecase = GetNovelChapterContentUseCase(MockNovelRepository());
        const novelId = "1";
        const catalogue = "1";
        // act
        final result = await usecase(Chapter(
            novelId: novelId, catalogue: catalogue, chapterId: catalogue));

        // assert
        expect(result.content, isNotEmpty);
      },
    );
  });
}
